//
//  File.cpp
//  DiceWar
//
//  Created by xiaofeng on 20/6/12.
//  Copyright (c) 2012 __MyCompanyName__. All rights reserved.
//

#include "RandomGenerator.h"
#include <ctime>
#include "cocos2d.h"

RandomGenerator::RandomGenerator()
{
    srand(time(NULL));
}

RandomGenerator::~RandomGenerator() {}

void RandomGenerator::shuffle(std::vector<int>& values)
{
    std::random_shuffle(values.begin(), values.end());
}

int RandomGenerator::getRandomNum(int upper)
{
    CCAssert(upper > 0, "Invalid parameter in RandomGenerator");
    return rand() % upper;
}

int RandomGenerator::getRandomNum(int lower, int upper)
{
    CCAssert(lower > 0, "Invalid parameter in RandomGenerator");
    CCAssert(lower < upper, "Invalid parameter in RandomGenerator");
    
    const int kDiff = upper - lower;
    return lower + rand() % kDiff;
}

void RandomGenerator::getRandomSegments(int number, int numSegements, std::vector<int>& segments)
{
    CCAssert(number > 0, "Invalid parameter in RandomGenerator");
    CCAssert(numSegements > 0 && numSegements < number, "Invalid parameter in RandomGenerator");
    
    segments.clear();
    for (int index = 0; index < numSegements; index++)
        segments.push_back(0);
    
    for (int currentNum = 1; currentNum <= number; currentNum++)
    {
        const int randomSegmentIndex = getRandomNum(numSegements);
        segments[randomSegmentIndex]++;
    }
}

void RandomGenerator::getRandomSegmentsWithPreAllocation(int number, int numSegements, std::vector<int>& segments)
{
    CCAssert(number > 0, "Invalid parameter in RandomGenerator");
    CCAssert(numSegements > 0 && numSegements < number, "Invalid parameter in RandomGenerator");
    CCAssert(segments.size() >= numSegements, "Invalid parameter in RandomGenerator");

    for (int currentNum = 1; currentNum <= number; currentNum++)
    {
        const int randomSegmentIndex = getRandomNum(numSegements);
        segments[randomSegmentIndex]++;
    }
}

void RandomGenerator::getRandomSegments(int number, int numSegements, int segmentLower, int segmentUpper, std::vector<int>& segments)
{
    CCAssert(number > 0, "Invalid parameter in RandomGenerator");
    CCAssert(numSegements > 0 && numSegements < number, "Invalid parameter in RandomGenerator");
    CCAssert(numSegements * segmentLower < number, "Invalid parameter in RandomGenerator");
    CCAssert(numSegements * segmentUpper > number, "Invalid parameter in RandomGenerator");
    
    segments.clear();
    for (int index = 0; index < numSegements; index++)
        segments.push_back(segmentLower);
    
    for (int currentNum = numSegements * segmentLower; currentNum <= number; currentNum++)
    {
        int randomSegmentIndex = getRandomNum(numSegements);
        while (segments[randomSegmentIndex] >= segmentUpper)
        {
            randomSegmentIndex = getRandomNum(numSegements);
        }
        segments[randomSegmentIndex]++;
    }
}

void RandomGenerator::getRandomSegmentsWithPreAllocation(int number, int numSegements, int segmentLower, int segmentUpper, std::vector<int>& segments)
{
    CCAssert(number > 0, "Invalid parameter in RandomGenerator");
    CCAssert(numSegements > 0 && numSegements < number, "Invalid parameter in RandomGenerator");
    
    for (int index = 0; index < numSegements; index++)
    {
        const int kCurrentValue = segments[index];
        if (kCurrentValue >= segmentLower) continue;
        segments[index] = segmentLower;
        number -= (segmentLower - kCurrentValue);
    }
    
    for (int currentNum = 1; currentNum <= number; currentNum++)
    {
        int randomSegmentIndex = getRandomNum(numSegements);
        while (segments[randomSegmentIndex] >= segmentUpper)
        {
            randomSegmentIndex = getRandomNum(numSegements);
        }
        segments[randomSegmentIndex]++;
    }
}
